package com.tj.ocr.img.sim;

import com.tj.ocr.img.BlankWhiteUtil;
import com.tj.ocr.img.LinePop;
import com.tj.ocr.img.MyImage;
import com.tj.ocr.util.ImageUtil;
import org.budo.support.java.security.util.DigestUtil;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

public class SimUtil {
    private static final int WIDTH_MIN = 14;

    /**
     * encode image
     * 1. len
     * 2.
     *
     * @param mi
     * @return
     */
    public static SimString encode(MyImage mi) {

        LinePop lpop = new LinePop(mi);
        MyImage tmi = lpop.pop(), tf = null;
        if (tmi == null)
            return new SimString(0, 0, 0, 0);

        //get header
        int header = getHeader(tmi);

        //get width
        int width = 0;
        while (tmi != null) {
            tf = tmi;
            width += getWidth(tmi);
            tmi = lpop.pop();
        }

        //get (simple) charactor
        long lr = 0;
        int[][] data = mi.getData();
        for (int col = 0; col < data.length; col++) {
            for (int row = 0; row < data[0].length; row++) {
                if (data[col][row] == 1)
                    lr++;
            }
        }

        //get footer
        int footer = getFooter(tf);

        return new SimString(width, lr, header, footer);
    }

    /**
     * encode image
     * 1. len
     * 2.
     *
     * @param image
     * @return
     */
    public static String encode(BufferedImage image) {
        MyImage mi = BlankWhiteUtil.procEx(image,170);
        SimString sim = encode(mi);
        return sim.toString();
    }

    private static int getWidth(MyImage tmi) {
        int ret = 0;

        int[][] data = tmi.getData();
        int widthEnd = tmi.getFromx() + tmi.getWidth();

        for (int col = tmi.getFromx(); col < widthEnd; col++) {
            for (int row = tmi.getFromy(); row < tmi.getFromy() + tmi.getHeight(); row++) {
                if (data[col][row] == 1) {
                    ret++;
                    break;
                }
            }
        }

        return ret;
    }

    private static int getFooter(MyImage tmi) {
        int ret = 0;

        int[][] data = tmi.getData();
        boolean bis = false;
        int lw = 0;
        for (int col = tmi.getFromx() + tmi.getWidth() - 1; col >= 0; col--) {
            int lh = 0;
            if (bis) {
                lw++;
                if (lw >= WIDTH_MIN)
                    break;
            }

            for (int row = tmi.getFromy(); row < tmi.getFromy() + tmi.getHeight(); row++) {
                if (data[col][row] == 1) {
                    bis = true;
                    lh++;
                }
            }

            ret += lw * 2 + lh;

        }

        return ret;
    }

    private static int getHeader(MyImage tmi) {
        int ret = 0;

        int[][] data = tmi.getData();
        boolean bis = false;
        int lw = 0;
        for (int col = tmi.getFromx(); col < tmi.getFromx() + tmi.getWidth(); col++) {
            int lh = 0;
            if (bis) {
                lw++;
                if (lw >= WIDTH_MIN)
                    break;
            }

            for (int row = tmi.getFromy(); row < tmi.getFromy() + tmi.getHeight(); row++) {
                if (data[col][row] == 1) {
                    bis = true;
                    lh++;
                }
            }

            ret += lw * 2 + lh;

        }

        return ret;
    }

    public static String imaeTextCode(BufferedImage image){
        image = ImageUtil.binaryzation(image);

        List<Rectangle> rectangles = splitRow(image);
        String code = "";
        for (Rectangle rectangle : rectangles) {
            BufferedImage rowImg = image.getSubimage((int) rectangle.getX(), (int) rectangle.getY(), (int) rectangle.getWidth(), (int) rectangle.getHeight());
            int w = rowImg.getWidth();
            int h = rowImg.getHeight();
            for (int i = 0; i < w; i++) {
                int value = 0;
                for (int j = 0; j < h; j++) {
                    if (ImageUtil.isBlack(rowImg.getRGB(i, j))) {
                        value++;
                    }
                }
                if (value != 0) {
                    code += value;
                }
            }
        }
        return DigestUtil.md5(code);
    }

    /**
     * 将图片拆分多个行
     *
     * @param image
     * @return
     */
    private static List<Rectangle> splitRow(BufferedImage image) {

        int width = image.getWidth(), height = image.getHeight();
        int[] textRow = {-1, -1};
        List<Rectangle> rectangles = new ArrayList<>();
        for (int j = 0; j < height; j++) {
            boolean isWhite = true;
            for (int i = 0; i < width; i++) {
                if (ImageUtil.isBlack(image.getRGB(i, j))) {
                    isWhite = false;
                }
            }
            if (isWhite && textRow[0] != -1) {
                textRow[1] = j - 1;
                Rectangle rectangle = new Rectangle(0, textRow[0], width, (textRow[1] - textRow[0]) + 1);
                rectangles.add(rectangle);
                textRow = new int[]{-1, -1};
            } else if (!isWhite && textRow[0] == -1) {
                textRow[0] = j;
            }
        }
        if (rectangles.isEmpty()) {   //只有一行时
            rectangles.add(new Rectangle(0, 0, width, height));
        }
        return rectangles;
    }
}
